package com.itheima.aop;

import com.alibaba.fastjson.JSON;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

@Component
@Aspect
@Slf4j
public class Aspect3 {

    //依赖注入
    @Autowired
    private OperateLogMapper operateLogMapper;

    @Autowired
    private HttpServletRequest request;

    @SneakyThrows
    @Around("execution(* com.itheima.controller.*.*(..)) && @annotation(com.itheima.aop.Log)")
    public Object before(ProceedingJoinPoint pjp) {
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        //创建记录日志的的 封装类对象，设置字段信息
        OperateLog log = new OperateLog();
        //1.获取操作人id，通过jwt令牌获取请求头中的token
        String jwt = request.getHeader("token");
        Claims claims = JwtUtils.parseJWT(jwt);
        Integer id = (Integer) claims.get("id");
        log.setOperateUser(id);

        //2.获取操作时间
        log.setOperateTime(LocalDateTime.now());

        //3.获取执行方法的全类名
        String className = pjp.getTarget().getClass().getName();
        log.setClassName(className);

        //4.获取执行方法名
        String methodName = pjp.getSignature().getName();
        log.setMethodName(methodName);

        //5.获取方法运行时的参数
        String params = Arrays.toString(pjp.getArgs());
        log.setMethodParams(params);

        //6.返回值
        log.setReturnValue(JSON.toJSONString( result));

        //7.获取方法时长
        long end = System.currentTimeMillis();
        log.setCostTime(end-start);

        //8.调mapper层，添加到数据库
        operateLogMapper.insert(log);

        return result;
    }
}
